using System;
using System.Drawing;
using System.Drawing.Imaging;
using Tao.OpenGl;

namespace Auxiliary.OpenGL
{
    public sealed class Texture2D : IDisposable
    {
        private int _handle;
        
        public Texture2D()
        {
            Gl.glGenTextures(1, out _handle);

            Gl.glBindTexture(Gl.GL_TEXTURE_2D, _handle);

            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);

            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
        }

        public void SetData(Bitmap bitmap)
        {
            Bind();

            Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);

            var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, data.Width, data.Height, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, data.Scan0);

            bitmap.UnlockBits(data);
        }

        public void Dispose()
        {
            Gl.glDeleteTextures(1, ref _handle);
            _handle = 0;
        }

        public void Bind()
        {
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, _handle);
        }

        public void UnBind()
        {
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);
        }
    }
}
